<template>
  <canvas ref="canvas" class="canvas-animation"></canvas>
</template>

<script>
export default {
  name: 'CanvasAnimation',
  data() {
    return {
      canvas: null,
      ctx: null,
      particles: [],
      mousePosition: { x: 0, y: 0 },
      dotCount: 150,
      dotRadius: 70,
      dotDistance: 90,
      mouseRadius: 200,
      connections: [] // 存储连接信息
    };
  },
  mounted() {
    this.initCanvas();
  },
  methods: {
    initCanvas() {
      this.canvas = this.$refs.canvas;
      this.ctx = this.canvas.getContext('2d');

      this.resizeCanvas();
      this.mousePosition.x = this.canvas.width / 2;
      this.mousePosition.y = this.canvas.height / 2;

      this.createDots();
      this.animateDots();

      window.addEventListener('resize', this.resizeCanvas);
      this.canvas.addEventListener('mousemove', this.mouseMove);
      this.canvas.addEventListener('mouseleave', this.mouseLeave);
    },
    createDots() {
      this.particles = [];
      for (let i = 0; i < this.dotCount; i++) {
        this.particles.push(new Dot(this.canvas));
      }
    },
    drawDot(dot) {
      this.ctx.beginPath();
      this.ctx.fillStyle = dot.color; // 使用点自身的颜色
      this.ctx.arc(dot.x, dot.y, dot.radius, 0, Math.PI * 2, false);
      this.ctx.fill();
    },
    moveDots() {
      for (const dot of this.particles) {
        if (dot.y < 0 || dot.y > this.canvas.height) {
          dot.vy = -dot.vy;
        }
        if (dot.x < 0 || dot.x > this.canvas.width) {
          dot.vx = -dot.vx;
        }
        dot.x += dot.vx;
        dot.y += dot.vy;
      }
    },
    connectDots() {
      this.connections = [];
      const nearbyDots = [];

      for (const dot of this.particles) {
        if (this.distanceToMouse(dot) < this.mouseRadius) {
          nearbyDots.push(dot);
        }
      }

      const limitedNearbyDots = nearbyDots.slice(0,35);

      for (let i = 0; i < limitedNearbyDots.length; i++) {
        for (let j = i + 1; j < limitedNearbyDots.length; j++) {
          const dot1 = limitedNearbyDots[i];
          const dot2 = limitedNearbyDots[j];

          const dx = dot1.x - dot2.x;
          const dy = dot1.y - dot2.y;
          const distance = Math.sqrt(dx * dx + dy * dy);

          if (distance < this.dotDistance) {
            const color = this.getMixedColor(dot1.linecolor, dot2.linecolor); // 混合两个点的颜色
            this.connections.push({ dot1, dot2, color });
          }
        }
      }
    },
    distanceToMouse(dot) {
      const dx = dot.x - this.mousePosition.x;
      const dy = dot.y - this.mousePosition.y;
      return Math.sqrt(dx * dx + dy * dy);
    },
    drawDots() {
      for (const dot of this.particles) {
        this.drawDot(dot);
      }
    },
    drawConnections() {
      for (const connection of this.connections) {
        this.ctx.beginPath();
        this.ctx.lineWidth = 1.5;
        this.ctx.strokeStyle = connection.color;
        this.ctx.moveTo(connection.dot1.x, connection.dot1.y);
        this.ctx.lineTo(connection.dot2.x, connection.dot2.y);
        this.ctx.stroke();
        this.ctx.closePath();
      }
    },
    animateDots() {
      this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
      this.moveDots();
      this.connectDots();
      this.drawConnections();
      this.drawDots();
      requestAnimationFrame(this.animateDots);
    },
    mouseMove(e) {
      this.mousePosition.x = e.pageX;
      this.mousePosition.y = e.pageY;
    },
    mouseLeave() {
      this.mousePosition.x = this.canvas.width / 2;
      this.mousePosition.y = this.canvas.height / 2;
    },
    resizeCanvas() {
      this.canvas.width = window.innerWidth;
      this.canvas.height = window.innerHeight / 3;
      this.createDots();
    },
    getMixedColor(color1, color2) {
      const rgba1 = color1.match(/\d+/g);
      const rgba2 = color2.match(/\d+/g);
      const r = (parseInt(rgba1[0]) + parseInt(rgba2[0])) / 2;
      const g = (parseInt(rgba1[1]) + parseInt(rgba2[1])) / 2;
      const b = (parseInt(rgba1[2]) + parseInt(rgba2[2])) / 2;
      return `rgba(${Math.round(r)}, ${Math.round(g)}, ${Math.round(b)}, 0.7)`;
    }
  },
  resizeCanvas() {
    this.canvas.width = window.innerWidth;
    this.canvas.height = window.innerHeight / 3;
    this.createDots();
  },
  beforeUnmount() {
    window.removeEventListener('resize', this.resizeCanvas);
    this.canvas.removeEventListener('mousemove', this.mouseMove);
    this.canvas.removeEventListener('mouseleave', this.mouseLeave);
  }
};

function Dot(canvas) {
  this.x = Math.random() * canvas.width;
  this.y = Math.random() * canvas.height;
  this.vx = (Math.random() - 0.5) * 2;
  this.vy = (Math.random() - 0.5) * 2;
  this.radius = Math.random() * 2 + 1;
  this.color =  'rgba(255, 255, 255, 0.8)';
  this.linecolor = `rgba(${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, ${Math.floor(Math.random() * 256)}, 0.7)`;
}
</script>
<style scoped>
.canvas-animation {
  display: block;
  background-color: var(--canvas-bg-color,#393d49);
  height: calc(100vh / 3); /* 根据视口高度调整 */
  z-index: 1; /* 设置较低的z-index */
  position: relative; /* 如果需要绝对定位 */
  overflow: hidden; /* 隐藏滚动条 */
  margin:20px auto 0 auto; /* 居中 */
}
/* 针对小屏幕的优化 */
@media screen and (max-width: 768px) {
 .canvas-animation {
    height: calc(100vh / 2);
  }
}
@media screen and (max-width: 480px) {
 .canvas-animation {
    display: none;
  }
}
</style>

